home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 20 code / Scripting the Finder / Zawphing / MenuHandler.cp < prev    next >
Encoding:
Text File  |  1994-10-11  |  9.7 KB  |  381 lines  |  [TEXT/MMCC]

  1. /*================================================================================
  2.     MenuHandler.c
  3.     
  4.     ©1991-4 Greg Anderson
  5.     greggor@apple.com
  6.     
  7.     Menu bar routines
  8. ================================================================================*/
  9. #include <Balloons.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <AppleEvents.h>
  13.  
  14. #include "MenuHandler.h"
  15. #include "WindowHandler.h"
  16.  
  17. #include "StringUtilities.h"
  18. #include "MenuTable.h"
  19. #include "AboutBox.h"
  20.  
  21. /*
  22. // Prototypes for private functions:
  23. */
  24. void                    FixupMenu( MenuHandle menuHand, short menu, short item );
  25. short                    NextLargestMenuID( short menuID );
  26. short                    FindItemID( short itemID );
  27. short                    FindMenuInTable( short menu, short item );
  28. void                    ProcessRange( short itemID, short groupSize, menuProc theProc, short param );
  29. void                    SetEnable( MenuHandle menuHand, short item, short enableFlag );
  30. void                    SetEnableRange( short itemID, short groupSize, short enableFlag );
  31. void                    DisableRange( short itemID, short groupSize );
  32. void                    EnableRange( short itemID, short groupSize );
  33. void                    CallCheckItem( MenuHandle menuHand, short item, short flag );
  34. void                    UncheckRange( short itemID, short groupSize );
  35. void                    DoDA( short theItem );
  36.  
  37. /*----------------------------------------------------------------------
  38. // SetupMenuBar
  39. //
  40. // Set up and display the menu bar
  41. ----------------------------------------------------------------------*/
  42. void SetupMenuBar(short startMenu, short endMenu)
  43. {
  44.     MenuHandle        menuHand;
  45.     MenuHandle        helpMenu;
  46.     Handle            menuResource;
  47.     char            menuTitle[256];
  48.     short            smallestMenuID = 0x7FFF;
  49.     short            numberOfMenus;
  50.     short            menuResourceID;
  51.     ResType            menuResourceType;
  52.     Str255            menuResourceName;
  53.     short            menuID;
  54.     short            item;
  55.     short            option;
  56.     OSErr            err;
  57.         
  58.     /*
  59.     // Load all of the menus.
  60.     */
  61.     for( menuResourceID=startMenu; menuResourceID <= endMenu; ++menuResourceID )
  62.     {
  63.         menuHand = GetMenu( menuResourceID );
  64.         if( menuHand )
  65.         {
  66.             /*
  67.             // Pull out the MENU ID of this menu.  The menu ID
  68.             // of a menu is DIFFERENT THAN its resource ID.
  69.             // The menu ID is the value that will be passed back
  70.             // to your application in the high word of the result
  71.             // of the function MenuSelect.
  72.             //
  73.             // Using ResEdit 2.1, you can set the Menu ID of
  74.             // a menu by selecting the "Edit Menu & MDEF ID"
  75.             // command in the "MENU" menu.
  76.             */
  77.             menuID = (*menuHand)->menuID;
  78.             /*
  79.             // Remember the ID of the menu with the smallest
  80.             // ID.  This menu is assumed to be the Apple Menu.
  81.             */
  82.             if( menuID < smallestMenuID )
  83.                 smallestMenuID = menuID;
  84.             /*
  85.             // Insert the menu in the menu bar
  86.             */
  87.             InsertMenu( menuHand, 0 );
  88.         }
  89.     }
  90.     /*
  91.     // Insert desk accessories into the Apple menu.
  92.     */
  93.     AddResMenu( GetMHandle(smallestMenuID),'DRVR');
  94.     
  95.     /*
  96.     // Draw the menu bar
  97.     */
  98.     DrawMenuBar();
  99. }
  100.  
  101. /*----------------------------------------------------------------------
  102. // FindItemID
  103. //
  104. // Find 'itemID' within the menuTable & return the index it was
  105. // found at
  106. ----------------------------------------------------------------------*/
  107. short FindItemID( short itemID )
  108. {
  109.     short        i;
  110.     
  111.     for(i=0;menuTable[i].itemID;++i)
  112.     {
  113.         if( menuTable[i].itemID == itemID )
  114.             return( i );
  115.     }
  116.     return( -1 );
  117. }
  118.  
  119. /*----------------------------------------------------------------------
  120. // AddItemIDtoTable
  121. //
  122. // Add an itemID to the menutable
  123. ----------------------------------------------------------------------*/
  124. void AddItemIDtoTable( short itemID, short menu, short item )
  125. {
  126.     short        i;
  127.     
  128.     i = FindItemID( itemID );
  129.     if( i != -1 )
  130.     {
  131.         menuTable[i].menu = menu;
  132.         menuTable[i].item = item;
  133.     }
  134. }
  135.  
  136. /*----------------------------------------------------------------------
  137. // FindMenuInTable
  138. //
  139. // Find 'itemID' within the menuTable & return the index it was
  140. // found at
  141. ----------------------------------------------------------------------*/
  142. short FindMenuInTable( short menu, short item )
  143. {
  144.     short        i;
  145.     
  146.     for(i=0;menuTable[i].itemID;++i)
  147.     {
  148.         if( (menuTable[i].menu == menu) && (menuTable[i].item == item) )
  149.             return( i );
  150.     }
  151.     return( -1 );
  152. }
  153.  
  154. /*----------------------------------------------------------------------
  155. // ProcessRange
  156. //
  157. // Process a range of menu item ids
  158. ----------------------------------------------------------------------*/
  159. void ProcessRange( short itemID, short groupSize, menuProc theProc, short param )
  160. {
  161.     MenuHandle    menuHand;
  162.     short        firstID;
  163.     short        i;
  164.     short        j;
  165.     
  166.     firstID = itemID - (itemID % groupSize);
  167.     for(j=firstID;j<firstID+groupSize;++j)
  168.     {
  169.         i = FindItemID(j);
  170.         if( i > -1 )
  171.         {
  172.             menuHand = GetMHandle(menuTable[i].menu);
  173.             if( menuHand != nil )
  174.                 (*theProc)(menuHand,menuTable[i].item,param);
  175.         }
  176.     }
  177. }
  178.  
  179. /*----------------------------------------------------------------------
  180. // SetEnable
  181. //
  182. // Used by SetEnableRange
  183. ----------------------------------------------------------------------*/
  184. void SetEnable( MenuHandle menuHand, short item, short enableFlag )
  185. {
  186.     if( enableFlag )
  187.         EnableItem(menuHand,item);
  188.     else
  189.         DisableItem(menuHand,item);
  190. }
  191.  
  192. /*----------------------------------------------------------------------
  193. // SetEnableRange
  194. //
  195. // Either enable or disable a range of menu items
  196. ----------------------------------------------------------------------*/
  197. void SetEnableRange( short itemID, short groupSize, short enableFlag )
  198. {
  199.     ProcessRange( itemID, groupSize, SetEnable, enableFlag );
  200. }
  201.  
  202. /*----------------------------------------------------------------------
  203. // DisableRange
  204. //
  205. // Disable a range of menu items
  206. ----------------------------------------------------------------------*/
  207. void DisableRange( short itemID, short groupSize )
  208. {
  209.     SetEnableRange( itemID, groupSize, false );
  210. }
  211.  
  212. /*----------------------------------------------------------------------
  213. // EnableRange
  214. //
  215. // Enable a range of menu items
  216. ----------------------------------------------------------------------*/
  217. void EnableRange( short itemID, short groupSize )
  218. {
  219.     SetEnableRange( itemID, groupSize, true );
  220. }
  221.  
  222. /*----------------------------------------------------------------------
  223. // CallCheckItem
  224. //
  225. // This routine is necessary because 'CheckItem' is an inline
  226. // function,and cannot be passed as a procedure pointer
  227. ----------------------------------------------------------------------*/
  228. void CallCheckItem( MenuHandle menuHand, short item, short flag )
  229. {
  230.     CheckItem(menuHand,item,flag);
  231. }
  232.  
  233. /*----------------------------------------------------------------------
  234. // UncheckRange
  235. //
  236. // Remove the check mark from any (& every) menu item in a given menu
  237. ----------------------------------------------------------------------*/
  238. void UncheckRange( short itemID, short groupSize )
  239. {
  240.     ProcessRange( itemID, groupSize, CallCheckItem, false );
  241. }
  242.  
  243. /*----------------------------------------------------------------------
  244. // CheckOneItem
  245. //
  246. // Place a check mark by one item in a menu; remove the checks from
  247. // all other items in the group
  248. ----------------------------------------------------------------------*/
  249. void CheckOneItem( short itemID, short groupSize )
  250. {
  251.     UncheckRange( itemID, groupSize );
  252.     ProcessRange( itemID, 1, CallCheckItem, true );
  253. }
  254.  
  255. /*----------------------------------------------------------------------
  256. // SetupMenuItems
  257. //
  258. // Enable all menus that need enabling; disable all that need
  259. // disabling; put check marks by the menus that need check marks.
  260. ----------------------------------------------------------------------*/
  261. void SetupMenuItems()
  262. {
  263.     OSErr err = noErr;
  264.     
  265.     /*
  266.     // Enable the "Close Window" menu item if there is an open window
  267.     */
  268.     SetEnableRange(M_CLOSEFRONT, 1, (FrontWindow() != nil));
  269.     
  270.     /*
  271.     // First, enable / disable all menus based
  272.     // on which of the menu's enable requirement
  273.     // flags match the menu enable flags in the
  274.     // frontmost window.
  275.     */
  276.     Try
  277.     {
  278.         FrontWindowHandler()->SetupMenus();
  279.     }
  280.     Catch(err)
  281.     {
  282.     }
  283. }
  284.  
  285. /*----------------------------------------------------------------------
  286. // ProcessMenuSelection
  287. //
  288. // Some Menu item selected; find out which one
  289. ----------------------------------------------------------------------*/
  290. void ProcessMenuSelection( long menuResult )
  291. {
  292.     GrafPtr        savePort;
  293.     Str255        selectionName;
  294.     char        selStr[256];
  295.     short        theItem        = menuResult & 0x0FFFF;
  296.     short        theMenu        = menuResult / 0x10000;
  297.     short        i;
  298.     
  299.     if( menuResult )
  300.     {
  301.         GetPort( &savePort );
  302.  
  303.         /*
  304.         // Find the index within the menu table of the item selected.
  305.         */
  306.         i = FindMenuInTable( theMenu, theItem );
  307.  
  308.         OSErr err = noErr;
  309.         Boolean frontWindowDidIt = false;
  310.         
  311.         Try
  312.         {
  313.             /*
  314.             // Give the front window a chance to process the menu command
  315.             */
  316.             frontWindowDidIt = FrontWindowHandler()->ProcessMenuSelection(menuTable[i].itemID);
  317.         }
  318.         Catch(err)
  319.         {
  320.         }
  321.         
  322.         if(frontWindowDidIt == false)
  323.         {
  324.             /*
  325.             // The apple menu is a special case...
  326.             */
  327.             if( theMenu == appleMenu )
  328.             {
  329.                 if(theItem == 1)
  330.                     ShowAboutBox();
  331.                 else
  332.                     DoDA(theItem);
  333.             }
  334.             else
  335.             {
  336.                 /*
  337.                 // If the front window didn't handle the command, and
  338.                 // if there is an entry in the menu function table,
  339.                 // then call it
  340.                 */
  341.                 if(menuTable[i].fMenuFunction != nil)
  342.                 {
  343.                     (*(menuTable[i].fMenuFunction))((CWindowPtr)FrontWindow(),menuTable[i].itemID);
  344.                 }
  345.             }
  346.         }
  347.         /*
  348.         // The OS hilites menus for us, but we must explicitly
  349.         // un-hilite the menu title after we have processed the
  350.         // command
  351.         */
  352.         HiliteMenu(0);
  353.         SetPort( savePort );
  354.     }
  355. }
  356.  
  357. /*----------------------------------------------------------------------
  358. // DoDA
  359. //
  360. // A Desk Accessory has been opened
  361. ----------------------------------------------------------------------*/
  362. void DoDA( short theItem )
  363. {
  364.     Str255        DAname;
  365.     
  366.     GetItem( GetMHandle(appleMenu), theItem, DAname );
  367.     OpenDeskAcc(DAname);
  368. }
  369.  
  370. /*----------------------------------------------------------------------
  371. // CloseFrontWindow
  372. //
  373. // Close the frontmost window
  374. ----------------------------------------------------------------------*/
  375. OSErr CloseFrontWindow(CWindowPtr window, short item)
  376. {
  377.     GetWindowHandler(FrontWindow())->CloseWindowByUser();
  378.     
  379.     return noErr;
  380. }
  381.